<?php
/**
 *  ### Using the alias `i0' for the tree index table
 *
 *
 */
namespace Dclub\modules\Catalog;

class Action_SelectTreePath
    extends Action_SelectTreeAbstract
{

    const TABLE_INDEX = 'i0';
    const TABLE_TREE  = 't0';
    const TABLE_CATALOG  = 'c0';

    /** The id of the tree node (category) to build path for
     *  @var int ?
     */
    protected $nodeId;

    /** The id of the item to build path for
     *  @var int ?
     */
    protected $itemId;

    /**
     *  @var string
     */
    protected $tableCatalog;


    /************************************
     *         Public methods          *
     ************************************/


    /**
     *  @param int $nodeId
     *  @return this
     */
    public function setNodeId( $nodeId )
    {
        debug();
        $this->nodeId = \Yz_Int::testNotNegative($nodeId);
        return $this;
    }

    /**
     *  @param int $itemId
     *  @return this
     */
    public function setItemId( $itemId )
    {
        debug();
        $this->itemId = \Yz_Int::testNotNegative($itemId);
        return $this;
    }

    /************************************
     *       Protected methods          *
     ************************************/


    /**
     *  Modified SELECT statement creator
     *
     */
    protected function buildSelect()
    {
        debug();
        if (null !== $this->itemId) {
            $builder = 'buildSelectForItemId';
        } else if (null !== $this->nodeId) {
            $builder = 'buildSelectForNodeId';
        } else {
            throw new \Yz_Exception("Neither node id nor item id set to fetch the path of");
        }
        $sql = parent::buildSelect();
        return $this->$builder($sql);
    }


    /**
     *
     */
    protected function buildSelectForItemId($sql)
    {
        debug();
        $ti = self::TABLE_INDEX;
        $tc = self::TABLE_CATALOG;

        // assume join with TABLE_INDEX already done
        return $sql
            ->joinTable(
                \Yz_SQL_Join::leftJoin($this->tableCatalog, $tc)
                    ->joinOn("{$ti}.id={$tc}.catId")
                )
            ->where("{$tc}.id=:_itemId")
            ->bind('_itemId', $this->itemId)
            ->orderBy("{$ti}.depth")
        ;
    }

    /**
     *
     */
    protected function buildSelectForNodeId($sql)
    {
        debug();
        $ti = self::TABLE_INDEX;

        // assume join with TABLE_INDEX already done
        return $sql
            ->where("{$ti}.id=:_nodeId")
            ->bind('_nodeId', $this->nodeId)
            ->orderBy("{$ti}.depth")
        ;
    }




    /** assign source tables and enforce correct join for the tables
     *  extend parent: add TABLE_CATALOG handling
     *  @param Yz_Hash $tableList
     *  @return chainable
     *  @throw Yz_Exception if table list empty
     *  @throw Yz_Exception if incorrect index table specification
     */
    protected function assignTables(\Yz_Hash $tableList)
    {
        parent::assignTables($tableList);
        $catTable = $tableList[self::TABLE_CATALOG];
        if (! is_string($catTable)) {
            throw new \Yz_Exception("Unrecognized tree table specification: string expected");
        }
        $this->tableCatalog = $catTable;
        return $this;
    }


    /** overridable/extensible join-builder
     *  by default, it joins only the index table
     *
     *  @param SQL_SELECT
     *  @return SQL_SELECT
     */
    protected function buildJoin($sql)
    {
        $t0 = self::TABLE_TREE;
        $ti = self::TABLE_INDEX;
        return $sql
            ->joinTable(
                \Yz_SQL_Join::leftJoin($this->tableIndex, self::TABLE_INDEX)
                    ->joinOn("{$ti}.parentId={$t0}.id")
            )
        ;
    }

}
